	#
	#  This is the Horizon Kickstart 
	#
	#  Copyright (C) 2002 by Francesco Frigo 
	#
	#  Tuesday 17th September, 2002
	# 
	#  Updated: Thursday 20th March, 2003
	#

.equ	VAdr , 0x80000000
.equ	PAdr , 0x100000
	
.global	start
.extern k_main

.global	GRUB_boot_header
.extern	_KERNEL_DATAEND
.extern	_KERNEL_END

.section .text		
start:	
	# 	jmp	start

	# GRUB Multiboot Header

	.long	0x1BADB002			# [9] - Magic
	.long	0x00010001			# Flags
	.long	0xE4514FFD			# checksum
	# extended header (because bit 16 is set)
	.long	PAdr				# header address
	.long	PAdr				# load address
	.long	_KERNEL_DATAEND-VAdr+PAdr	# load_end address
	.long	_KERNEL_END-VAdr+PAdr		# bss_end address
	.long	core-VAdr+PAdr			# entry point

	
	#
	# Begin of system's code
	# 

core:
	# We don't have a valid IDT yet, so interrupts are better be disabled :-)
	cli

	# Load temporary GDT
        lgdt    TempGDTR-VAdr+PAdr


	# Make a jump to use the correct selector (0x18 = TEMP_CODE)
	ljmp     $0x18,$here
here:	
	

	# Set up data segments
	movw	$0x0020,%ax	# TEMP_DATA
	movw	%ax,%ds
	movw	%ax,%es
	movw	%ax,%fs
	movw	%ax,%gs
	movw	%ax,%ss

	# Set up kernel stack
	movl	$StackTop,%esp
	movl	$StackBase,%ebp

	# Load null LDT
	xorw	%ax,%ax
	lldt	%ax


	# Save GRUB Boot Header pointer
	movl	%ebx,GRUB_boot_header
	
	# Clear screen
	#         mov     edi,0xB8000	# Pointer to Video Memory
	#         mov     cx,1000
	#         xor     eax,eax
	#         rep     stosd
	

	
	# print an A on the top left of the screen
	# 	 	mov	edi,0x7FFB8000
	# 	 	mov	ax,0x0741
	# 	 	mov	[edi],ax	


	# movl	$0x7FFB8000,%edi
	# movw	$0x0741,%ax
	# mov	%ax,(%edi)
	# cli
	# hlt
	
	# clear flags
	# some versions of GRUB leave the NT flag on... which causes problems
	pushl	$0x02
	popfl
	
	# Jump into kernel
	# Further initialization will be done there

kern_jump:
	# Clear registers before jumping into the kernel	
	xor	%eax,%eax
	xor	%ebx,%ebx
	xor	%ecx,%ecx
	xor	%edx,%edx
	xor	%esi,%esi
	xor	%edi,%edi

	# Jump into the kernel's entry point
	call	k_main

stop_now:	
	cli
	hlt
	jmp	stop_now	


.section .data
	
GRUB_boot_header:	.long	0
			
TempGDT:	
1:	
	# 0x00 - NULL SELECTOR 	
        .long      0,0				# zero

	# 0x08 - CODE SELECTOR (ZERO BASED)
	.word      0xFFFF,0x0000		# limit=FFFF,base=0000
	.byte      0x00,0x9A,0xCF,0x00		# page gran,big

	# 0x10 - DATA SELECTOR (ZERO BASED)
	.word      0xFFFF,0x0000		# limit=FFFF,base=0000
	.byte      0x00,0x92,0xCF,0x00		# page gran,big

	# Note: next selectors base is set to 0x80100000 (2 GiB)

	# 0x18 - CODE SELECTOR (TEMP)
	.word      0xFFFF,0x0000		# limit=FFFF,base=80100000
	.byte      0x10,0x9A,0xCF,0x80		# page gran,big

	# 0x20 - DATA SELECTOR (TEMP)
	.word      0xFFFF,0x0000		# limit=FFFF,base=80100000
	.byte      0x10,0x92,0xCF,0x80		# page gran,big
2:
	
TempGDTR:
        .word      2b-1b-1		# limit
        .long      TempGDT-VAdr+PAdr	# base
	
.section .bss

	# Temp kernel stack
StackBase:	
	.space 4096 , 0
StackTop:	
